﻿using System;
using System.ServiceModel.Channels;
using Hopscotch.Common.Contracts.AppService;
using Hopscotch.Common.Services.Wcf;
using Hopscotch.Domain.Common;

namespace Hopscotch.Common.Communication.WcfClients
{
    public abstract class DomainServiceClient<T, TKey> : IDomainService<T, TKey>
        where T : DomainBase<TKey>
        where TKey : struct
    {
        private readonly IClientProxyFactory<IDomainService<T, TKey>> domainServiceFactory;

        public DomainServiceClient(IClientProxyFactory<IDomainService<T, TKey>> domainServiceFactory)
        {
            this.domainServiceFactory = domainServiceFactory;
        }

        public string Ping()
        {
            var client = domainServiceFactory.CreateChannel();
            try
            {
                string result = client.Ping();
                ((IChannel)client).Close();
                return result;
            }
            catch (Exception)
            {
                ((IChannel)client).Abort();
                throw;
            }
        }

        public T Get(TKey id)
        {
            var client = domainServiceFactory.CreateChannel();
            try
            {
                T entity = client.Get(id);
                ((IChannel)client).Close();

                return entity;
            }
            catch (Exception)
            {
                ((IChannel)client).Abort();
                throw;
            }
        }

        public T Save(T t)
        {
            var client = domainServiceFactory.CreateChannel();
            try
            {
                T T = client.Save(t);
                ((IChannel)client).Close();

                return T;
            }
            catch (Exception)
            {
                ((IChannel)client).Abort();
                throw;
            }
        }

        public void Delete(T t)
        {
            var client = domainServiceFactory.CreateChannel();
            try
            {
                client.Delete(t);
                ((IChannel)client).Close();
            }
            catch (Exception)
            {
                ((IChannel)client).Abort();
                throw;
            }
        }
    }
}
